package com.kly.sc.api.application.controller.order;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.fqgj.base.services.redis.RedisClient;
import com.fqgj.common.api.Response;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.common.utils.StringUtils;
import com.kly.dto.*;
import com.kly.enums.BenefitsStatus;
import com.kly.enums.OrderStatus;
import com.kly.enums.TradeResultStatus;
import com.kly.sc.api.application.constant.ApiRedisKeys;
import com.kly.sc.api.application.helper.RequestLocalInfo;
import com.kly.sc.api.application.service.utils.BaseComponent;
import com.kly.sc.api.application.utils.RpcUtils;
import com.kly.service.*;
import com.kly.service.pay.GooglePayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 会员
 */
@Slf4j
@RestController
@RequestMapping("api/member")
public class MemberController extends BaseComponent {

    @Resource
    MemberService memberService;

    @Resource
    MemberBenefitsService memberBenefitsService;

    @Resource
    RedisClient redisClient;

    @Resource
    UserVasPurchasesService userVasPurchasesService;

    @Resource
    GooglePayService googlePayService;

    @Resource
    ProductService productService;

    @Resource
    TOrderService orderService;

    private final static Integer VALID = 1;

    /**
     * 查询会员信息
     */
    @RequestMapping("/query")
    public Response getMemberInfo() {
        String userCode = RequestLocalInfo.getCurrentUser().getUserCode();
        MemberDto memberDto = retrieveMemberFromCacheOrService(userCode);
        if (memberDto != null) {
            if (RequestLocalInfo.getRequestBasicInfo().getVersionControl() == 1) {
                memberDto.getMemberDescription().setContent("Enjoy 4 premium benefits");
                return Response.ok(memberDto);
            } else {
                return Response.ok(memberDto);
            }

        }
        return Response.error(TradeResultStatus.NO_MEMBER);
    }

    /**
     * 修改会员自动订阅
     *
     * @return
     */
    @RequestMapping("/offAutoRenew")
    public Response offAutoRenew() {

        String userCode = getCurrentUserCode();
        String appCode = RequestLocalInfo.getRequestBasicInfo().getAppCode();
        log.info("===offAutoRenew===, userCode:{}", userCode);

        final TOrderDto order = RpcUtils.getResult(orderService.queryLatestSubscriptionsOrderByUserCode(userCode));
        if (Objects.isNull(order)) {
            return Response.error("The subscription not exists in records");
        }

        if (OrderStatus.CLOSE.getStatus() == order.getStatus()) {
            return Response.error("The order has closed");
        }

        final String purchaseToken = order.getPurchaseToken();
        if (StringUtils.isEmpty(purchaseToken)) {
            return Response.error("The subscription's token not exists in records");
        }


        final ProductDto productDto = RpcUtils.getResult(productService.queryProductsByProductCode(appCode, order.getProductCode()));
        final String productConfig = productDto.getProductConfig();
        if (StringUtils.isEmpty(productConfig)) {
            return Response.error("Illegal subscription configuration");
        }
        final JSONObject configs = JSONObject.parseObject(productConfig);

        final Boolean cancel = RpcUtils.getResult(googlePayService.cancelSubscription(configs.getString("packageName"),
                configs.getString("purchaseProductName"), purchaseToken));
        if (cancel) {
            // 取消权益
            memberService.offAutoRenew(userCode);
            // 关闭订单
//            closedOrder(order);

            //修改会员信息后，删除会员缓存
            redisClient.del(ApiRedisKeys.USER_MEMBER.getValue(), userCode);
            log.info("===offAutoRenewSuccess===, userCode:{}, orderNo:{}", userCode, order.getOrderNo());
            return Response.ok();
        }
        log.info("===offAutoRenewFailed===, userCode:{}, orderNo:{}", userCode, order.getOrderNo());
        return Response.error("Unsubscribe failed");

    }

    private void closedOrder(TOrderDto order) {
        TOrderDto tOrderDto = new TOrderDto();
        tOrderDto.setOrderNo(order.getOrderNo());
        tOrderDto.setStatus(OrderStatus.CLOSE.getStatus());
        tOrderDto.setBenefitsStatus(BenefitsStatus.INVALID.getStatus());
        RpcUtils.getResult(orderService.updateOrder(tOrderDto));
    }

    /**
     * @return 会员权益集合
     */
    @RequestMapping("/queryBenefits")
    public Response queryMemberBenefits() {
        String userCode = RequestLocalInfo.getCurrentUser().getUserCode();
        // 是否会员
        Boolean isMember = RpcUtils.getResult(memberService.ifMember(userCode));

        // 获取用户会员权益（包括已过期会员但未消费的权益记录), 非会员返回为空
        List<MemberBenefitsDto> memberBenefitsData = RpcUtils.getResult(memberBenefitsService.getMemberBenefits(userCode));
        // 额外购买的flashchat/pp/pv使用次数
        List<UserVasPurchasesDto> benefitsData = RpcUtils.getResult(userVasPurchasesService.getUserPurchasesBenefits(userCode, null));

        if (CollectionUtils.isNotEmpty(memberBenefitsData)) {
            for (MemberBenefitsDto memberBenefitsDto : memberBenefitsData) {
                if (CollectionUtils.isNotEmpty(benefitsData)) {
                    final UserVasPurchasesDto purchasesDto = benefitsData.stream().filter(o -> o.getBenefitCode().equals(memberBenefitsDto.getBenefitCode())).findFirst().orElse(null);
                    if (purchasesDto != null) {
                        Integer additionalBenefitCount = purchasesDto.getAdditionalBenefitCount() == null ? 0 : purchasesDto.getAdditionalBenefitCount();
                        memberBenefitsDto.setMaxUses(memberBenefitsDto.getMaxUses() + purchasesDto.getUsageCount() + additionalBenefitCount);

                    }
                }
                memberBenefitsDto.setStatus(isMember ? VALID : null);
            }
            return Response.ok(memberBenefitsData);
        } else {
            List<MemberBenefitsDto> list = new ArrayList<>();
            for (UserVasPurchasesDto purchasesDto : benefitsData) {
                MemberBenefitsDto memberBenefitsDto = new MemberBenefitsDto();
                BeanUtil.copyProperties(purchasesDto, memberBenefitsDto);
                memberBenefitsDto.setMaxUses(purchasesDto.getUsageCount());
                list.add(memberBenefitsDto);
            }
            return Response.ok(list);
        }
    }
}
